package com.haoyun.mirage.gateway;

import com.haoyun.common.cache.anno.EnableMethodCache;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.util.UrlPathHelper;

import java.nio.charset.Charset;
import java.util.Arrays;

@EnableZuulProxy
@EnableOAuth2Client
@EnableFeignClients
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableMethodCache
@SpringBootApplication(scanBasePackages = "com.haoyun")
@EnableConfigurationProperties(value = GatewayApplication.FilterConfiguration.class)
public class GatewayApplication {
    /**
     * 当配置中心使用git估计会有效，读取本地配置文件无效。
     *
     * @return
     */
    @Bean
    @RefreshScope
    @ConfigurationProperties("zuul")
    public ZuulProperties zuulProperties() {
        return new ZuulProperties();
    }

    @Bean
    public PatternServiceRouteMapper serviceRouteMapper() {
        return new PatternServiceRouteMapper("(?<name>.*)-(?<version>v.*$)", "${version}/${name}");
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setDefaultEncoding(Charset.defaultCharset().name());
        source.setUrlPathHelper(urlPathHelper);
        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setMaxAge(Long.MAX_VALUE);
        corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
        corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setAllowedMethods(Arrays.asList(HttpMethod.OPTIONS.name(),
                HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name(),
                HttpMethod.DELETE.name(), HttpMethod.PUT.name()));
        source.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(source);
    }

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }


    @Getter
    @Setter
    @ConfigurationProperties("zuul.filter")
    public class FilterConfiguration {
        private String root;
        private Integer interval;
    }


//	@Bean
//	public FilterLoader filterLoader(FilterConfiguration filterConfiguration){
//		FilterLoader filterLoader = FilterLoader.getInstance();
//		filterLoader.setCompiler(new GroovyCompiler());
//		FilterFileManager.setFilenameFilter(new GroovyFileFilter());
//		try {
//			FilterFileManager.init(filterConfiguration.getInterval(),filterConfiguration.getRoot()+"/pre");
//		} catch (Exception e) {
//			throw new RuntimeException(e);
//		}
//		return filterLoader;
//	}
}
